<template>
  <div>
    <h2 class="mb-4">地图配置</h2>
    <a-form :model="form" layout="vertical">
      <a-form-item label="地图服务商" name="provider">
        <a-select v-model:value="form.provider" placeholder="请选择地图服务商">
          <a-select-option value="baidu">百度地图</a-select-option>
          <a-select-option value="mock">模拟地图</a-select-option>
        </a-select>
      </a-form-item>

      <template v-if="form.provider === 'baidu'">
        <a-form-item label="AK" name="ak">
          <a-input-password v-model:value="form.ak" placeholder="请输入百度地图AK" />
        </a-form-item>
      </template>

      <template v-if="form.provider === 'mock'">
        <a-alert
          message="模拟地图模式"
          description="模拟地图模式下，所有地图操作将返回模拟数据，仅用于开发测试。"
          type="warning"
          show-icon
        />
      </template>

      <a-form-item>
        <a-space>
          <a-button type="primary" @click="handleSave">保存配置</a-button>
          <a-button @click="handleTest">测试连接</a-button>
        </a-space>
      </a-form-item>
    </a-form>

    <!-- 测试区域 -->
    <div class="test-area">
      <a-collapse v-model:activeKey="activeKey" :bordered="false">
        <a-collapse-panel key="1" :show-arrow="false">
          <template #header>
            <div class="collapse-header">
              <h2 class="mb-0">地图测试</h2>
              <a-button type="link" @click.stop="toggleTest">
                {{ isExpanded ? '收起' : '展开' }}
                <down-outlined :class="{ 'rotate-icon': isExpanded }" />
              </a-button>
            </div>
          </template>

          <!-- 地址解析测试 -->
          <div class="test-section">
            <h3 class="mb-4">地址解析</h3>
            <a-form :model="geocodeForm" layout="vertical">
              <a-form-item label="地址" name="address">
                <a-input v-model:value="geocodeForm.address" placeholder="请输入要解析的地址" />
              </a-form-item>
              <a-form-item>
                <a-button type="primary" @click="handleGeocode" :loading="geocoding">
                  解析地址
                </a-button>
              </a-form-item>
            </a-form>
            <div v-if="geocodeResult" class="result-box">
              <h3>解析结果</h3>
              <p>经度：{{ geocodeResult.lng }}</p>
              <p>纬度：{{ geocodeResult.lat }}</p>
              <p>详细地址：{{ geocodeResult.formattedAddress }}</p>
              <p>坐标系：{{ geocodeResult.coordinateType }}</p>
            </div>
          </div>

          <!-- 逆地址解析测试 -->
          <div class="test-section mt-4">
            <h3 class="mb-4">逆地址解析</h3>
            <a-form :model="reverseGeocodeForm" layout="vertical">
              <a-form-item label="经度" name="lng">
                <a-input v-model:value="reverseGeocodeForm.lng" placeholder="请输入经度" />
              </a-form-item>
              <a-form-item label="纬度" name="lat">
                <a-input v-model:value="reverseGeocodeForm.lat" placeholder="请输入纬度" />
              </a-form-item>
              <a-form-item label="坐标系" name="coordinateType">
                <a-select v-model:value="reverseGeocodeForm.coordinateType">
                  <a-select-option value="WGS84">WGS84</a-select-option>
                  <a-select-option value="GCJ02">GCJ02(火星坐标系)</a-select-option>
                  <a-select-option value="BD09">BD09(百度坐标系)</a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item>
                <a-button type="primary" @click="handleReverseGeocode" :loading="reverseGeocoding">
                  解析坐标
                </a-button>
              </a-form-item>
            </a-form>
            <div v-if="reverseGeocodeResult" class="result-box">
              <h3>解析结果</h3>
              <p>详细地址：{{ reverseGeocodeResult.formattedAddress }}</p>
              <p>省份：{{ reverseGeocodeResult.province || '未知' }}</p>
              <p>城市：{{ reverseGeocodeResult.city || '未知' }}</p>
              <p>区县：{{ reverseGeocodeResult.district || '未知' }}</p>
              <p>街道：{{ reverseGeocodeResult.street || '未知' }}</p>
              <p>门牌号：{{ reverseGeocodeResult.streetNumber || '未知' }}</p>
            </div>
          </div>

          <!-- 坐标转换测试 -->
          <div class="test-section mt-4">
            <h3 class="mb-4">坐标转换</h3>
            <a-form :model="convertForm" layout="vertical">
              <a-form-item label="经度" name="lng">
                <a-input v-model:value="convertForm.lng" placeholder="请输入经度" />
              </a-form-item>
              <a-form-item label="纬度" name="lat">
                <a-input v-model:value="convertForm.lat" placeholder="请输入纬度" />
              </a-form-item>
              <a-form-item label="源坐标系" name="fromType">
                <a-select v-model:value="convertForm.fromType">
                  <a-select-option value="WGS84">WGS84</a-select-option>
                  <a-select-option value="GCJ02">GCJ02(火星坐标系)</a-select-option>
                  <a-select-option value="BD09">BD09(百度坐标系)</a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item label="目标坐标系" name="toType">
                <a-select v-model:value="convertForm.toType">
                  <a-select-option value="WGS84">WGS84</a-select-option>
                  <a-select-option value="GCJ02">GCJ02(火星坐标系)</a-select-option>
                  <a-select-option value="BD09">BD09(百度坐标系)</a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item>
                <a-button type="primary" @click="handleConvert" :loading="converting">
                  转换坐标
                </a-button>
              </a-form-item>
            </a-form>
            <div v-if="convertResult" class="result-box">
              <h3>转换结果</h3>
              <p>转换后经度：{{ convertResult.lng }}</p>
              <p>转换后纬度：{{ convertResult.lat }}</p>
              <p>坐标系：{{ convertResult.coordinateType }}</p>
            </div>
          </div>
        </a-collapse-panel>
      </a-collapse>
    </div>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { DownOutlined } from '@ant-design/icons-vue'
import axios, { AxiosError } from 'axios'

const form = reactive({
  provider: '',
  ak: ''
})

// 地址解析表单
const geocodeForm = reactive({
  address: ''
})

// 逆地址解析表单
const reverseGeocodeForm = reactive({
  lng: '',
  lat: '',
  coordinateType: 'BD09'
})

// 坐标转换表单
const convertForm = reactive({
  lng: '',
  lat: '',
  fromType: 'WGS84',
  toType: 'BD09'
})

// 加载状态
const geocoding = ref(false)
const converting = ref(false)
const reverseGeocoding = ref(false)

// 结果数据
interface GeocodeResult {
  lng: number
  lat: number
  formattedAddress: string
  coordinateType: string
}

interface ReverseGeocodeResult {
  formattedAddress: string
  province: string
  city: string
  district: string
  street: string
  streetNumber: string
}

interface ConvertResult {
  lng: number
  lat: number
  coordinateType: string
}

const geocodeResult = ref<GeocodeResult | null>(null)
const convertResult = ref<ConvertResult | null>(null)
const reverseGeocodeResult = ref<ReverseGeocodeResult | null>(null)

// 从本地存储加载配置
const loadConfig = () => {
  const savedConfig = localStorage.getItem('mapConfig')
  if (savedConfig) {
    const config = JSON.parse(savedConfig)
    form.provider = config.provider
    if (config.provider === 'baidu') {
      form.ak = config.ak
    }
  }
}

// 保存配置到本地存储
const saveConfig = () => {
  const config = {
    provider: form.provider,
    ...(form.provider === 'baidu' && { ak: form.ak })
  }
  localStorage.setItem('mapConfig', JSON.stringify(config))
}

const handleSave = async () => {
  try {
    const config = {
      type: form.provider,
      ...form.provider === 'baidu' && {
        ak: form.ak
      }
    }
    
    const response = await axios.post('/api/map/switch', config)
    if (response.status === 200) {
      message.success('地图配置保存成功')
      saveConfig()
    }
  } catch (error) {
    const err = error as AxiosError
    message.error('保存地图配置失败：' + err.message)
  }
}

const handleTest = async () => {
  try {
    const testAddress = '北京市朝阳区'
    const response = await axios.post('/api/map/geocode', testAddress)
    if (response.status === 200) {
      message.success('地图配置测试成功')
    }
  } catch (error) {
    const err = error as AxiosError
    message.error('地图配置测试失败：' + err.message)
  }
}

// 地址解析
const handleGeocode = async () => {
  if (!geocodeForm.address) {
    message.error('请输入要解析的地址')
    return
  }
  try {
    geocoding.value = true
    const response = await axios.post('/api/map/geocode', geocodeForm.address)
    if (response.data && response.data.success) {
      geocodeResult.value = {
        lng: response.data.location.longitude,
        lat: response.data.location.latitude,
        formattedAddress: (response.data.address || response.data.formattedAddress || '').replace(/=$/, ''),
        coordinateType: response.data.location.coordinateType
      }
      message.success('地址解析成功')
    } else {
      message.error('地址解析失败：' + (response.data.message || '未知错误'))
    }
  } catch (error) {
    const err = error as AxiosError
    message.error('地址解析失败：' + err.message)
  } finally {
    geocoding.value = false
  }
}

// 逆地址解析
const handleReverseGeocode = async () => {
  if (!reverseGeocodeForm.lng || !reverseGeocodeForm.lat) {
    message.error('请输入要解析的坐标')
    return
  }

  try {
    reverseGeocoding.value = true
    const response = await axios.post('/api/map/reverse-geocode', {
      longitude: Number(reverseGeocodeForm.lng),
      latitude: Number(reverseGeocodeForm.lat),
      coordinateType: reverseGeocodeForm.coordinateType
    })
    if (response.data && response.data.success) {
      const result = response.data
      reverseGeocodeResult.value = {
        formattedAddress: result.formattedAddress || result.address || '未知',
        province: result.province || '未知',
        city: result.city || '未知',
        district: result.district || '未知',
        street: result.street || '未知',
        streetNumber: result.streetNumber || '未知'
      }
      message.success('逆地址解析成功')
    } else {
      message.error('逆地址解析失败：' + (response.data.message || '未知错误'))
    }
  } catch (error) {
    const err = error as AxiosError
    message.error('逆地址解析失败：' + err.message)
  } finally {
    reverseGeocoding.value = false
  }
}

// 坐标转换
const handleConvert = async () => {
  if (!convertForm.lng || !convertForm.lat) {
    message.error('请输入要转换的坐标')
    return
  }

  try {
    converting.value = true
    const response = await axios.post('/api/map/convert', {
      longitude: Number(convertForm.lng),
      latitude: Number(convertForm.lat)
    }, {
      params: {
        fromType: convertForm.fromType,
        toType: convertForm.toType
      }
    })
    if (response.data && response.data.success) {
      convertResult.value = {
        lng: response.data.location.longitude,
        lat: response.data.location.latitude,
        coordinateType: response.data.location.coordinateType
      }
      message.success('坐标转换成功')
    } else {
      message.error('坐标转换失败：' + (response.data.message || '未知错误'))
    }
  } catch (error) {
    const err = error as AxiosError
    message.error('坐标转换失败：' + err.message)
  } finally {
    converting.value = false
  }
}

// 折叠面板状态
const activeKey = ref<string[]>([])
const isExpanded = ref(false)

// 切换折叠状态
const toggleTest = () => {
  isExpanded.value = !isExpanded.value
  activeKey.value = isExpanded.value ? ['1'] : []
}

// 组件挂载时加载配置
onMounted(() => {
  loadConfig()
})
</script>

<style scoped>
.mb-4 {
  margin-bottom: 16px;
}
.mt-4 {
  margin-top: 16px;
}
.test-area {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid #f0f0f0;
}
.test-section {
  background: #fafafa;
  padding: 16px;
  border-radius: 4px;
}
.result-box {
  margin-top: 16px;
  padding: 16px;
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 4px;
}
.collapse-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}
.collapse-header h2 {
  margin: 0;
}
.rotate-icon {
  transform: rotate(180deg);
  transition: transform 0.3s;
}
:deep(.ant-collapse-header) {
  padding: 0 !important;
}
:deep(.ant-collapse-content) {
  border-top: none !important;
}
:deep(.ant-collapse-item) {
  border: none !important;
}
</style>